package com.doudou.oauth.token;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author: 傻男人
 * @Date: 2020/5/20 16:36
 * @Version: 1.0
 * @Description: 定制 AccessToken 转换器，为添加额外信息在服务器端获取做准备
 */
@Component
public class CustomAccessTokenConverter extends DefaultAccessTokenConverter implements UserAuthenticationConverter{

    /**
     * Extract information about the user to be used in an access token (i.e. for resource servers).
     *
     * @param authentication an authentication representing a user
     * @return a map of key values representing the unique information about the user
     */
    @Override
    public Map<String, ?> convertUserAuthentication(Authentication authentication) {
        LinkedHashMap response = new LinkedHashMap();
        response.put("user_name", authentication.getName());
        response.put("name", ((User) authentication.getPrincipal()).getUsername());
        if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
            response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
        }
        return response;
    }

    /**
     * 解析身份信息
     * @param claims
     * @return
     */
    @Override
    public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
        OAuth2Authentication authentication
                = super.extractAuthentication(claims);
        authentication.setDetails(claims);
        return authentication;
    }

    /**
     * 向token中添加自定义信息
     * @param token
     * @param authentication
     * @return
     */
    @Override
    public Map<String, Object> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
        Map result =  super.convertAccessToken(token, authentication);
        OAuth2Request request = authentication.getOAuth2Request();
        request.getExtensions().entrySet().stream().forEach(e->{
            result.put(e.getKey(),e.getValue());
        });
        return result;
    }
}

